﻿using System.Collections.Generic;
using System.IO;
using System.Text;
using CID.Domain.Infrastructure;
using CID.Execution.Agent.TemplateHandling;
using CID.Execution.Support.Information;
using CID.Execution.Support.TemplateHandling;
using NUnit.Framework;

namespace CID.Execution.Agent.Tests.TemplateHandling
{
    [TestFixture]
    class BATTEmplateHandlerTests : BaseAgentTests
    {
        private const string ValidTemplateContentFilePath = @".\Artifacts\ValidBATTemplate.bat";
        private const string InvalidTemplateContentFilePath = @".\Artifacts\InvalidBATTemplate.bat";
        private static readonly ParameterValueInfo Parameter1Value = new ParameterValueInfo() { ParameterName = "ParameterOne", ParameterType = ParameterType.String, StringValue = "Some string value" };
        private static readonly ParameterValueInfo Parameter2Value = new ParameterValueInfo() { ParameterName = "ParameterTwo", ParameterType = ParameterType.String, StringValue = "Another string value" };
        private static readonly ParameterValueInfo Parameter3Value = new ParameterValueInfo() { ParameterName = "ParameterThree", ParameterType = ParameterType.Integer, IntegerValue = 123 };
        private static readonly ParameterValueInfo OutputFileParameterValue = new ParameterValueInfo() { ParameterName = "OutputFilePath", ParameterType = ParameterType.String, StringValue = ".\\Output File.txt" };
        
        private BATTemplateHandler handler;
        private TemplateInfo templateInfo;
        private IEnumerable<ParameterValueInfo> parameterValues;
        private IEnumerable<ParameterValueInfo> additionalParameterValues;
        private IEnumerable<ServerInfo> targetServers;
        private string outputFilePath;

        public override void SetUp()
        {
            base.SetUp();

            outputFilePath = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), "Output File.txt");
            handler = new BATTemplateHandler();
            templateInfo = new TemplateInfo() { Content = File.ReadAllBytes(ValidTemplateContentFilePath), Name = "Template" };
            parameterValues = new ParameterValueInfo[] { Parameter1Value, Parameter2Value, Parameter3Value };
            additionalParameterValues = new ParameterValueInfo[] { OutputFileParameterValue };
            targetServers = new ServerInfo[] { new ServerInfo() { Name="SomeServer", Address="Address" } };
            OutputFileParameterValue.StringValue = outputFilePath;
        }

        public override void TearDown()
        {
            base.TearDown();

            if (File.Exists(outputFilePath)) File.Delete(outputFilePath);
        }

        [Test]
        public void Execute_ValidTemplate_ShouldSucceed()
        {
            handler.ExecuteTemplate(templateInfo, parameterValues, additionalParameterValues, targetServers, new StringBuilder());

            Assert.IsTrue(File.Exists(outputFilePath));
            var outputFileContent = File.ReadAllText(outputFilePath);
            StringAssert.Contains(Parameter1Value.StringValue, outputFileContent);
            StringAssert.Contains(Parameter2Value.StringValue, outputFileContent);
            StringAssert.Contains(Parameter3Value.IntegerValue.Value.ToString(), outputFileContent);
        }

        [Test, ExpectedException(typeof(TemplateHandlingException))]
        public void Execute_InvalidTemplate_ShouldThrowExceptionAndAbort()
        {
            templateInfo.Content = File.ReadAllBytes(InvalidTemplateContentFilePath);

            handler.ExecuteTemplate(templateInfo, parameterValues, additionalParameterValues, targetServers, new StringBuilder());
        }
    }
}
